#pragma __COLLECTIONS_INCLUDES__

#ifndef COLLECTIONS_HPP
#define	COLLECTIONS_HPP

#include <iostream>

namespace lms {
    
    namespace collections {

        template<class TEntity>
        class Node {
        private:
            TEntity *data;
            Node<TEntity> *previous;
            Node<TEntity> *next;

        public:
            Node();
            Node(TEntity *entity);
            TEntity* getData();
            Node<TEntity>* getPrevious();
            Node<TEntity>* getNext();

            void setData(TEntity *entity);
            void setPrevious(Node<TEntity> *entity);
            void setNext(Node<TEntity> *entity);
        };

        template<class TEntity>
        class LinkedList {
        private:
            Node<TEntity> *first;
            Node<TEntity> *last;
            Node<TEntity>* getNodeByIndex(int index);
            int length;

        public:
            LinkedList();
            Node<TEntity>* getFirst();
            Node<TEntity>* getLast();
            TEntity* getByIndex(int index);
            void add(TEntity *entity);
            void edit(TEntity *entity, int index);
            void remove(int index);
            bool isEmpty();
            int getLength();
        };

        template<class TEntity>
        class Queue {
        private:
            Node<TEntity> *first;
            Node<TEntity> *last;
            int length;

        public:
            Queue();
            Node<TEntity>* getFirst();
            Node<TEntity>* getLast();
            int getLength();
            void enQueue(TEntity* entity);
            Node<TEntity>* deQueue();
        };

        template<class TEntity>
        class Stack {
        private:
            Node<TEntity> *first;
            Node<TEntity> *last;
            int length;

        public:
            Stack();
            Node<TEntity>* getFirst();
            Node<TEntity>* getLast();
            void push(TEntity* entity);
            Node<TEntity>* pop();
            int getLength();
        };
    }
}

#endif	/* COLLECTIONS_HPP */

